package cn.edu.xmu.oomall.liquidation.service;

import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.liquidation.dao.ExpenditureDao;
import cn.edu.xmu.oomall.liquidation.dao.LiquidationDao;
import cn.edu.xmu.oomall.liquidation.dao.RevenueDao;
import cn.edu.xmu.oomall.liquidation.microservice.*;
import cn.edu.xmu.oomall.liquidation.microservice.vo.*;
import cn.edu.xmu.oomall.liquidation.model.bo.*;
import cn.edu.xmu.oomall.liquidation.model.po.*;
import cn.edu.xmu.oomall.liquidation.model.vo.*;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

/**
 * @author HertzLiu
 * @version 2021/12/4 10:58
 * @package_name cn.edu.xmu.oomall.liquidation
 * @project_name oomall
 * @product_name IntelliJ IDEA
 * @description
 */

@Service
public class LiquidationService {

    @Autowired
    private LiquidationDao liquidationDao;

    @Autowired
    private ExpenditureDao expenditureDao;

    @Autowired
    private RevenueDao revenueDao;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ShareService shareService;


    @Autowired
    private AfterSaleService afterSaleService;

    /**
     * @return cn.edu.xmu.oomall.core.util.ReturnObject
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<List<Map<String, Object>>> getLiquidationState() {
        List<Map<String, Object>> stateList = new ArrayList<>();
        for (Liquidation.State state : Liquidation.State.values()) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("code", state.getCode());
            temp.put("name", state.getDescription());
            stateList.add(temp);
        }
        return new ReturnObject<List<Map<String, Object>>>(stateList);
    }

    /**
     * @param shopId
     * @param beginTime
     * @param endTime
     * @param state
     * @param page
     * @param pageSize
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<com.github.pagehelper.PageInfo < cn.edu.xmu.oomall.core.model.VoObject>>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<PageInfo<VoObject>> getLiquidatedList(Long shopId, LocalDateTime beginTime, LocalDateTime endTime, Byte state, Integer page, Integer pageSize) {
        LiquidationPoExample liquidationPoExample = new LiquidationPoExample();
        LiquidationPoExample.Criteria criteria = liquidationPoExample.createCriteria();

        if (shopId != null) {
            criteria.andShopIdEqualTo(shopId);
        }
        if (beginTime != null) {
            criteria.andLiquidDateGreaterThan(beginTime);
        }
        if (endTime != null) {
            criteria.andLiquidDateLessThan(endTime);
        }
        if (state != null) {
            criteria.andStateEqualTo(state);
        }

        PageInfo<LiquidationPo> liquidationPoPageInfo = liquidationDao.getLiquidatedListPageInfo(liquidationPoExample, page, pageSize).getData();
        List<LiquidationPo> liquidationPoList = liquidationPoPageInfo.getList();
        List<VoObject> liquidatedListRetVos = new ArrayList<>();

        for (LiquidationPo liquidationPo : liquidationPoList) {
            SimpleObjectVo simpleShopRetVo = new SimpleObjectVo(liquidationPo.getShopId(), liquidationPo.getShopName());
            LiquidatedList liquidationList = new LiquidatedList(liquidationPo.getId(), simpleShopRetVo, liquidationPo.getLiquidDate(), liquidationPo.getExpressFee(), liquidationPo.getCommission(), liquidationPo.getShopRevenue(), liquidationPo.getPoint(), liquidationPo.getState());

            LiquidatedListRetVo liquidatedListRetVo = cloneVo(liquidationList, LiquidatedListRetVo.class);
            liquidatedListRetVos.add(liquidatedListRetVo);
        }

        return new ReturnObject<>(getPageInfoRetVo(liquidatedListRetVos, liquidationPoPageInfo));
    }

    /**
     * @param shopId
     * @param id
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<cn.edu.xmu.oomall.core.model.VoObject>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<Object> getLiquidatedListDetail(Long shopId, Long id) {

        ReturnObject<Object> returnObject = liquidationDao.getLiquidatedListDetail(shopId, id);
        if (returnObject.getCode() != ReturnNo.OK) {
            return returnObject;
        }
        LiquidationPo liquidationPo = (LiquidationPo) returnObject.getData();
        SimpleObjectVo simpleShopRetVo = new SimpleObjectVo(liquidationPo.getShopId(), liquidationPo.getShopName());
        SimpleObjectVo simpleModifierRetVo = new SimpleObjectVo(liquidationPo.getModifierId(), liquidationPo.getModifierName());
        SimpleObjectVo simpleCreatorRetVo = new SimpleObjectVo(liquidationPo.getCreatorId(), liquidationPo.getCreatorName());
        LiquidatedListDetail liquidatedListDetail = new LiquidatedListDetail(liquidationPo.getId(), simpleShopRetVo, liquidationPo.getLiquidDate(), liquidationPo.getExpressFee(), liquidationPo.getCommission(), liquidationPo.getPoint(), liquidationPo.getShopRevenue(), liquidationPo.getState(), simpleCreatorRetVo, liquidationPo.getGmtCreate(), liquidationPo.getGmtModified(), simpleModifierRetVo);

        LiquidatedListDetailRetVo liquidatedListDetailRetVo = cloneVo(liquidatedListDetail, LiquidatedListDetailRetVo.class);
        return new ReturnObject<>(liquidatedListDetailRetVo);
    }

    /**
     * @param shopId
     * @param orderId
     * @param productId
     * @param page
     * @param pageSize
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<com.github.pagehelper.PageInfo < cn.edu.xmu.oomall.core.model.VoObject>>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<PageInfo<VoObject>> getRevenue(Long shopId, Long orderId, Long productId, Long liquidationId, Integer page, Integer pageSize) {


        RevenueItemPoExample revenueItemPoExample = new RevenueItemPoExample();
        RevenueItemPoExample.Criteria criteria = revenueItemPoExample.createCriteria();

        if (shopId != null) {
            criteria.andShopIdEqualTo(shopId);
        }
        if (orderId != null) {
            criteria.andOrderIdEqualTo(orderId);
        }
        if (liquidationId != null) {
            criteria.andLiquidIdEqualTo(liquidationId);
        }
        if (productId != null) {
            criteria.andProductIdEqualTo(productId);
        }
        PageInfo<RevenueItemPo> revenueItemPoPageInfo = revenueDao.getRevenueListPageInfo(revenueItemPoExample, page, pageSize).getData();
        List<RevenueItemPo> revenueItemPoList = revenueItemPoPageInfo.getList();
        List<VoObject> revenueItemRetVos = new ArrayList<>();
        SimpleObjectVo simpleShopRetVo = getSimpleShopRetVoByShopId(shopId);
        for (RevenueItemPo revenueItemPo : revenueItemPoList) {
            addRevenueItemPoToReturnVos(revenueItemPo, revenueItemRetVos, simpleShopRetVo);
        }

        return new ReturnObject<>(getPageInfoRetVo(revenueItemRetVos, revenueItemPoPageInfo));
    }

    /**
     * @param shopId
     * @param orderId
     * @param productId
     * @param page
     * @param pageSize
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<com.github.pagehelper.PageInfo < cn.edu.xmu.oomall.core.model.VoObject>>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<PageInfo<VoObject>> getExpenditure(Long shopId, Long orderId, Long productId, Long liquidationId, Integer page, Integer pageSize) {

        SimpleObjectVo simpleShopRetVo = getSimpleShopRetVoByShopId(shopId);
        ExpenditureItemPoExample expenditureItemPoExample = new ExpenditureItemPoExample();
        ExpenditureItemPoExample.Criteria expenditureCriteria = expenditureItemPoExample.createCriteria();

        if (shopId != null) {
            expenditureCriteria.andShopIdEqualTo(shopId);
        }
        if (orderId != null) {
            expenditureCriteria.andOrderIdEqualTo(orderId);
        }
        if (liquidationId != null) {
            expenditureCriteria.andLiquidIdEqualTo(liquidationId);
        }
        if (productId != null) {
            expenditureCriteria.andProductIdEqualTo(productId);
        }
        PageInfo<ExpenditureItemPo> expenditureItemPoPageInfo = expenditureDao.getExpenditureListPageInfo(expenditureItemPoExample, page, pageSize).getData();
        List<ExpenditureItemPo> expenditureItemPoList = expenditureItemPoPageInfo.getList();
        List<VoObject> expenditureItemRetVos = new ArrayList<>();
        for (ExpenditureItemPo expenditureItemPo : expenditureItemPoList) {
            addExpenditureItemPoToReturnVos(expenditureItemPo, expenditureItemRetVos, simpleShopRetVo);
        }

        return new ReturnObject<>(getPageInfoRetVo(expenditureItemRetVos, expenditureItemPoPageInfo));
    }

    /**
     * @param shopId
     * @param id
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<cn.edu.xmu.oomall.core.model.VoObject>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<Object> getRevenueFromExpenditure(Long shopId, Long id) {
        SimpleObjectVo simpleShopRetVo = getSimpleShopRetVoByShopId(shopId);

        ReturnObject<Object> returnObject = expenditureDao.getExpenditureById(shopId, id);
        if (returnObject.getCode() != ReturnNo.OK) {
            return returnObject;
        }
        ExpenditureItemPo expenditureItemPo = (ExpenditureItemPo) returnObject.getData();
        Long revenueId = expenditureItemPo.getRevenueId();

        returnObject = revenueDao.getRevenueById(shopId, revenueId);
        if (returnObject.getCode() != ReturnNo.OK) {
            return returnObject;
        }
        RevenueItemPo revenueItemPo = (RevenueItemPo) returnObject.getData();
        SimpleObjectVo simpleProductRetVo = new SimpleObjectVo(revenueItemPo.getProductId(), revenueItemPo.getProductName());
        SimpleObjectVo simpleCreatorRetVo = new SimpleObjectVo(revenueItemPo.getCreatorId(), revenueItemPo.getCreatorName());
        SimpleObjectVo simpleModifierRetVo = new SimpleObjectVo(revenueItemPo.getModifierId(), revenueItemPo.getModifierName());
        GeneralLedger generalLedger = new GeneralLedger(revenueItemPo.getId(), simpleShopRetVo, simpleProductRetVo, revenueItemPo.getAmount(), revenueItemPo.getCommission(), revenueItemPo.getPoint(), revenueItemPo.getShopRevenue(), revenueItemPo.getExpressFee(), simpleCreatorRetVo, revenueItemPo.getGmtCreate(), revenueItemPo.getGmtModified(), simpleModifierRetVo);

        GeneralLedgerRetVo revenueItemRetVo = cloneVo(generalLedger, GeneralLedgerRetVo.class);
        return new ReturnObject<>(revenueItemRetVo);
    }

    /**
     * @param beginTime
     * @param endTime
     * @param page
     * @param pageSize
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<com.github.pagehelper.PageInfo < cn.edu.xmu.oomall.core.model.VoObject>>
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description todo: 修改逻辑
     */
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public ReturnObject<PageInfo<VoObject>> getPointRecordsRevenue(LocalDateTime beginTime, LocalDateTime endTime, Integer page, Integer pageSize) {
        RevenueItemPoExample revenueItemPoExample = new RevenueItemPoExample();
        RevenueItemPoExample.Criteria revenueCriteria = revenueItemPoExample.createCriteria();

        LiquidationPoExample liquidationPoExample = new LiquidationPoExample();
        LiquidationPoExample.Criteria liquidationCriteria = liquidationPoExample.createCriteria();

        if (beginTime != null) {
            liquidationCriteria.andLiquidDateGreaterThan(beginTime);
        }
        if (endTime != null) {
            liquidationCriteria.andLiquidDateLessThan(endTime);
        }

        List<LiquidationPo> liquidationPoList = liquidationDao.getLiquidatedList(liquidationPoExample).getData();
        List<Long> liquidationIdList = new ArrayList<>();
        for (LiquidationPo liquidationPo : liquidationPoList) {
            liquidationIdList.add(liquidationPo.getId());
        }

        if (liquidationIdList.size() != 0) {
            revenueCriteria.andLiquidIdIn(liquidationIdList);
        }

        PageInfo<RevenueItemPo> revenueItemPoListPageInfo = revenueDao.getRevenueListPageInfo(revenueItemPoExample, page, pageSize).getData();
        List<RevenueItemPo> revenueItemPoList = revenueItemPoListPageInfo.getList();
        List<VoObject> revenueItemRetVo = new ArrayList<>();
        for (RevenueItemPo revenueItemPo : revenueItemPoList) {
            SimpleObjectVo simpleShopVo = getSimpleShopRetVoByShopId(revenueItemPo.getShopId());
            addRevenueItemPoToReturnVos(revenueItemPo, revenueItemRetVo, simpleShopVo);
        }
        return new ReturnObject<>(getPageInfoRetVo(revenueItemRetVo, revenueItemPoListPageInfo));
    }

    /**
     * @param beginTime
     * @param endTime
     * @param page
     * @param pageSize
     * @return cn.edu.xmu.oomall.core.util.ReturnObject<com.github.pagehelper.PageInfo < cn.edu.xmu.oomall.core.model.VoObject>>
     * @author HertzLiu
     * @createTime 2021/12/17 22:47
     * @description
     */
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public ReturnObject<PageInfo<VoObject>> getPointRecordsExpenditure(LocalDateTime beginTime, LocalDateTime endTime, Integer page, Integer pageSize) {
        ExpenditureItemPoExample expenditureItemPoExample = new ExpenditureItemPoExample();
        ExpenditureItemPoExample.Criteria expenditureCriteria = expenditureItemPoExample.createCriteria();

        LiquidationPoExample liquidationPoExample = new LiquidationPoExample();
        LiquidationPoExample.Criteria liquidationCriteria = liquidationPoExample.createCriteria();

        if (beginTime != null) {
            liquidationCriteria.andLiquidDateGreaterThan(beginTime);
        }
        if (endTime != null) {
            liquidationCriteria.andLiquidDateLessThan(endTime);
        }

        List<LiquidationPo> liquidationPoList = liquidationDao.getLiquidatedList(liquidationPoExample).getData();
        List<Long> liquidationIdList = new ArrayList<>();
        for (LiquidationPo liquidationPo : liquidationPoList) {
            liquidationIdList.add(liquidationPo.getId());
        }

        if (liquidationIdList.size() != 0) {
            expenditureCriteria.andLiquidIdIn(liquidationIdList);
        }

        PageInfo<ExpenditureItemPo> expenditureItemPoListPageInfo = expenditureDao.getExpenditureListPageInfo(expenditureItemPoExample, page, pageSize).getData();
        List<ExpenditureItemPo> expenditureItemPoList = expenditureItemPoListPageInfo.getList();
        List<VoObject> expenditureItemRetVo = new ArrayList<>();
        for (ExpenditureItemPo expenditureItemPo : expenditureItemPoList) {
            SimpleObjectVo simpleShopVo = getSimpleShopRetVoByShopId(expenditureItemPo.getShopId());
            addExpenditureItemPoToReturnVos(expenditureItemPo, expenditureItemRetVo, simpleShopVo);
        }
        return new ReturnObject<>(getPageInfoRetVo(expenditureItemRetVo, expenditureItemPoListPageInfo));
    }

    /**
     * @param shopId
     * @return cn.edu.xmu.oomall.liquidation.model.vo.SimpleShopRetVo
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    public SimpleObjectVo getSimpleShopRetVoByShopId(Long shopId) {
        LiquidationPoExample liquidationPoExample = new LiquidationPoExample();
        LiquidationPoExample.Criteria criteria = liquidationPoExample.createCriteria();
        criteria.andShopIdEqualTo(shopId);
        String shopName = (String) liquidationDao.getShopNameByShopId(liquidationPoExample).getData();
        return new SimpleObjectVo(shopId, shopName);
    }

    /**
     * @param revenueItemPo
     * @param RetVos
     * @param simpleShopRetVo
     * @return void
     * @author HertzLiu
     * @createTime 2021/12/15 0:58
     * @description
     */
    public void addRevenueItemPoToReturnVos(RevenueItemPo revenueItemPo, List<VoObject> RetVos, SimpleObjectVo simpleShopRetVo) {

        SimpleObjectVo simpleProductRetVo = new SimpleObjectVo(revenueItemPo.getProductId(), revenueItemPo.getProductName());
        SimpleObjectVo simpleCreatorRetVo = new SimpleObjectVo(revenueItemPo.getCreatorId(), revenueItemPo.getCreatorName());
        SimpleObjectVo simpleModifierRetVo = new SimpleObjectVo(revenueItemPo.getModifierId(), revenueItemPo.getModifierName());
        GeneralLedger generalLedger = new GeneralLedger(revenueItemPo.getId(), simpleShopRetVo, simpleProductRetVo, revenueItemPo.getAmount(), revenueItemPo.getCommission(), revenueItemPo.getPoint(), revenueItemPo.getShopRevenue(), revenueItemPo.getExpressFee(), simpleCreatorRetVo, revenueItemPo.getGmtCreate(), revenueItemPo.getGmtModified(), simpleModifierRetVo);

        GeneralLedgerRetVo generalLedgerRetVo = cloneVo(generalLedger, GeneralLedgerRetVo.class);
        RetVos.add(generalLedgerRetVo);
    }

    /**
     * @param expenditureItemPo
     * @param RetVos
     * @param simpleShopRetVo
     * @return void
     * @author HertzLiu
     * @createTime 2021/12/15 0:59
     * @description
     */
    public void addExpenditureItemPoToReturnVos(ExpenditureItemPo expenditureItemPo, List<VoObject> RetVos, SimpleObjectVo simpleShopRetVo) {

        SimpleObjectVo simpleProductRetVo = new SimpleObjectVo(expenditureItemPo.getProductId(), expenditureItemPo.getProductName());
        SimpleObjectVo simpleCreatorRetVo = new SimpleObjectVo(expenditureItemPo.getCreatorId(), expenditureItemPo.getCreatorName());
        SimpleObjectVo simpleModifierRetVo = new SimpleObjectVo(expenditureItemPo.getModifierId(), expenditureItemPo.getModifierName());
        GeneralLedger generalLedger = new GeneralLedger(expenditureItemPo.getId(), simpleShopRetVo, simpleProductRetVo, expenditureItemPo.getAmount(), expenditureItemPo.getCommission(), expenditureItemPo.getPoint(), expenditureItemPo.getShopRevenue(), expenditureItemPo.getExpressFee(), simpleCreatorRetVo, expenditureItemPo.getGmtCreate(), expenditureItemPo.getGmtModified(), simpleModifierRetVo);

        GeneralLedgerRetVo generalLedgerRetVo = cloneVo(generalLedger, GeneralLedgerRetVo.class);
        RetVos.add(generalLedgerRetVo);
    }

    /**
     * @param retVos
     * @param poPageInfo
     * @return com.github.pagehelper.PageInfo<cn.edu.xmu.oomall.core.model.VoObject>
     * @author HertzLiu
     * @createTime 2021/12/15 1:00
     * @description
     */
    public PageInfo<VoObject> getPageInfoRetVo(List<VoObject> retVos, PageInfo poPageInfo) {
        PageInfo<VoObject> RetVoPageInfo = PageInfo.of(retVos);
        RetVoPageInfo.setPageNum(poPageInfo.getPageNum());
        RetVoPageInfo.setPages(poPageInfo.getPages());
        RetVoPageInfo.setPageSize(poPageInfo.getPageSize());
        RetVoPageInfo.setTotal(poPageInfo.getTotal());
        return RetVoPageInfo;
    }

    /**
     * @return cn.edu.xmu.oomall.core.util.ReturnObject
     * @author HertzLiu
     * @createTime 2021/12/16 16:03
     * @description
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject startLiquidate(StartInfoVo startInfoVo, Long adminId, String adminName) {
        StartInfo startInfo = new StartInfo(startInfoVo.getBeginTime(), startInfoVo.getEndTime());
        //清算单Map，键为商铺id，值为商铺本次清算的清算单
        Map<Long, Liquidation> liquidationMap = new HashMap<>();
        //插入平台的清算单
        LiquidationPo tempLiquidationPlatformPo = new LiquidationPo();
        tempLiquidationPlatformPo.setShopId(0L);
        //插入数据库获取id
        ReturnObject retObj = liquidationDao.insertLiquidationPo(tempLiquidationPlatformPo, adminId, adminName);
        if (retObj.getCode().getCode() != 0) {
            return retObj;
        }
        Liquidation liquidationPlatform = cloneVo(retObj.getData(), Liquidation.class);
        liquidationPlatform.setExpressFee(0L);
        liquidationPlatform.setCommission(0L);
        liquidationPlatform.setShopId(0L);
        liquidationPlatform.setLiquidDate(LocalDateTime.now());
        liquidationMap.put(0L, liquidationPlatform);
        //平台总快递费 平台总佣金
        Long platformExpressFee = 0L;
        Long platformCommission = 0L;

        // 支付（入账）清算
        InternalReturnObject<PageVo<PaymentVo>> paymentVoListInternalRetObj = paymentService.getPaymentList(startInfo.getBeginTime(), startInfo.getEndTime());
        if (paymentVoListInternalRetObj.getErrno() != 0) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "支付单据获取失败");
        }
        List<PaymentVo> paymentList = paymentVoListInternalRetObj.getData().getList();

        System.out.println("paymentList----------------------" + paymentList);
        // 平台级别开始
        for (PaymentVo payment : paymentList) {
            // 订单级别开始
            if (payment.getDocumentType() == 0) {
                InternalReturnObject simpleOrderVoInternalRetObj = orderService.getOrderById(Long.parseLong(payment.getDocumentId()));
                if (simpleOrderVoInternalRetObj.getErrno() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "订单收款时订单信息获取失败");
                }
                //记录此订单金额的变量
                Long orderShopRevenue = 0L;
                Long orderShopPoints = 0L;
                Long orderShopExpressFee = 0L;
                Long orderShopCommission = 0L;
                //订单信息
                SimpleOrderVo simpleOrderVo = (SimpleOrderVo) simpleOrderVoInternalRetObj.getData();
                var putRObj = putLiquadation(liquidationMap, simpleOrderVo.getShopId(), adminId, adminName);
                if (!putRObj.getCode().equals(ReturnNo.OK)) {
                    return putRObj;
                }

                InternalReturnObject<PageVo<OrderItemVo>> orderItemListInternalRetObj = orderService.getOrderItemsByOrderId(Long.parseLong(payment.getDocumentId()));
                if (orderItemListInternalRetObj.getErrno() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "订单收款时订单明细获取失败");
                }
                System.out.println("orderItemVoList--------------" + orderItemListInternalRetObj);
                // 明细级别开始
                List<OrderItemVo> orderItemVoList = orderItemListInternalRetObj.getData().getList();
                for (OrderItemVo orderItemVo : orderItemVoList) {
                    InternalReturnObject commissionRateInternalRetObj = goodsService.getCommissionRate(orderItemVo.getProductId());
                    if (commissionRateInternalRetObj.getErrno() != 0) {
                        return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "获取平台抽成比例失败");
                    }
                    Integer commissionRatio = (Integer) commissionRateInternalRetObj.getData();

                    Long point = 0L;
                    Long sharerId = null;
                    InternalReturnObject<PointVo> pointInternalRetObj = shareService.calculatePoints(orderItemVo.getId());

                    if (pointInternalRetObj != null) {
                        if (pointInternalRetObj.getErrno() != 0) {
                            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "计算返点失败");
                        }
                        point = pointInternalRetObj.getData().getPoint();
                        sharerId = pointInternalRetObj.getData().getShareId();
                    }

                    System.out.println("orderItemVo-------------------" + orderItemVo);
                    //计算一笔订单明细的清算金额
                    Long amount = (orderItemVo.getPrice() - orderItemVo.getDiscountPrice()) * orderItemVo.getQuantity();
                    //计算佣金
                    Long commission = (commissionRatio * amount / 100);
                    //商铺收入
                    Long orderItemShopRevenue = amount - commission - point / 100;

                    RevenueItemPo shopOrderRevenuePo = new RevenueItemPo();
                    shopOrderRevenuePo.setPaymentId(payment.getId());
                    shopOrderRevenuePo.setLiquidId(liquidationMap.get(simpleOrderVo.getShopId()).getId());
                    shopOrderRevenuePo.setShopId(orderItemVo.getShopId());
                    shopOrderRevenuePo.setOrderId(simpleOrderVo.getId());
                    shopOrderRevenuePo.setOrderitemId(orderItemVo.getId());
                    shopOrderRevenuePo.setProductId(orderItemVo.getProductId());
                    shopOrderRevenuePo.setProductName(orderItemVo.getName());
                    shopOrderRevenuePo.setAmount(amount);
                    shopOrderRevenuePo.setQuantity(Math.toIntExact(orderItemVo.getQuantity()));
                    shopOrderRevenuePo.setExpressFee(0L);
                    shopOrderRevenuePo.setCommission(commission);
                    shopOrderRevenuePo.setPoint(point);
                    shopOrderRevenuePo.setSharerId(sharerId);
                    shopOrderRevenuePo.setShopRevenue(orderItemShopRevenue);

                    // 向入账单中插入
                    ReturnObject ret = revenueDao.insertRevenueItemPo(shopOrderRevenuePo, adminId, adminName);
                    if (ret.getCode().getCode() != 0) {
                        return ret;
                    }

                    orderShopRevenue += orderItemShopRevenue;
                    orderShopPoints += point;
                    orderShopCommission += commission;
                } // 明细级别结束
                //修改清算单map
                orderShopExpressFee = simpleOrderVo.getExpressFee();
                Liquidation liquidation = liquidationMap.get(simpleOrderVo.getShopId());
                liquidation.setExpressFee(liquidation.getExpressFee() + orderShopExpressFee);
                liquidation.setCommission(liquidation.getCommission() + orderShopCommission);
                liquidation.setPoint(liquidation.getPoint() + orderShopPoints);
                liquidation.setShopRevenue(liquidation.getShopRevenue() + orderShopRevenue);
                liquidationMap.put(simpleOrderVo.getShopId(), liquidation);

                platformExpressFee += orderShopExpressFee;
                platformCommission += orderShopCommission;
            } // 订单级别结束

            System.out.println("LiquidationMap 1----------------------");
            System.out.println(liquidationMap);

            // 售后级别开始
            if (payment.getDocumentType() == 4L) {
                InternalReturnObject simpleAfterSaleVoInternalRetObj = afterSaleService.getAfterSalesById(Long.parseLong(payment.getDocumentId()));
                if (simpleAfterSaleVoInternalRetObj.getErrno() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "售后支付单据获取失败");
                }
                AftersalesVo simpleAfterSaleVo = JSON.parseObject(JacksonUtil.toJson(simpleAfterSaleVoInternalRetObj.getData()), AftersalesVo.class);
                var putRObj = putLiquadation(liquidationMap, simpleAfterSaleVo.getShopId(), adminId, adminName);
                if (!putRObj.getCode().equals(ReturnNo.OK)) {
                    return putRObj;
                }
                InternalReturnObject orderItemVoInternalRetObj = orderService.getOrderItemById(simpleAfterSaleVo.getOrderItemId());
                if (orderItemVoInternalRetObj.getErrno() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "售后支付时订单详情信息获取失败");
                }

                OrderItemVo orderItemVo = JSON.parseObject(JacksonUtil.toJson(orderItemVoInternalRetObj.getData()), OrderItemVo.class);

                RevenueItemPo shopAfterSaleRevenuePo = new RevenueItemPo();
                shopAfterSaleRevenuePo.setLiquidId(liquidationMap.get(orderItemVo.getShopId()).getId());
                shopAfterSaleRevenuePo.setPaymentId(payment.getId());
                shopAfterSaleRevenuePo.setShopId(orderItemVo.getShopId());
                shopAfterSaleRevenuePo.setOrderId(orderItemVo.getOrderId());
                shopAfterSaleRevenuePo.setOrderitemId(orderItemVo.getId());
                shopAfterSaleRevenuePo.setProductId(orderItemVo.getProductId());
                shopAfterSaleRevenuePo.setProductName(orderItemVo.getName());
                shopAfterSaleRevenuePo.setAmount(simpleAfterSaleVo.getPrice());
                shopAfterSaleRevenuePo.setQuantity(Math.toIntExact(simpleAfterSaleVo.getQuantity()));
                shopAfterSaleRevenuePo.setShopRevenue(simpleAfterSaleVo.getPrice());

                // 向入账单中插入
                System.out.println("insertRevenueItemPo========================" + shopAfterSaleRevenuePo);
                ReturnObject ret = revenueDao.insertRevenueItemPo(shopAfterSaleRevenuePo, adminId, adminName);
                if (ret.getCode().getCode() != 0) {
                    return ret;
                }

                Liquidation liquidation = liquidationMap.get(simpleAfterSaleVo.getShopId());
                liquidation.setShopRevenue(liquidation.getShopRevenue() + shopAfterSaleRevenuePo.getShopRevenue());
                liquidationMap.put(simpleAfterSaleVo.getShopId(), liquidation);
            }
            System.out.println("LiquidationMap 2----------------------");
            System.out.println(liquidationMap);
            // todo: 改变payment支付状态为已清算
        } // 平台级别结束
        // 支付（入账）清算结束
        //平台快递费入账
        RevenueItemPo expFeeRevenueItemPo = new RevenueItemPo();
        expFeeRevenueItemPo.setLiquidId(liquidationMap.get(0L).getId());
        expFeeRevenueItemPo.setShopId(0L);
        expFeeRevenueItemPo.setOrderId(0L);
        expFeeRevenueItemPo.setOrderitemId(0L);
        expFeeRevenueItemPo.setAmount(platformExpressFee);
        expFeeRevenueItemPo.setExpressFee(platformExpressFee);
        ReturnObject expFeeRevenueReturnObject = revenueDao.insertRevenueItemPo(expFeeRevenueItemPo, adminId, adminName);
        if (expFeeRevenueReturnObject.getCode().getCode() != 0) {
            return expFeeRevenueReturnObject;
        }
        // 退款（出账）清算开始
        InternalReturnObject<PageVo<RefundVo>> refundVoListInternalRetObj = paymentService.getRefundList(0L, startInfo.getBeginTime(), startInfo.getEndTime());
        if (refundVoListInternalRetObj.getErrno() != 0) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "退款单据获取失败");
        }
        List<RefundVo> refundList = refundVoListInternalRetObj.getData().getList();
        Long refundExpFee = 0L;
        for (RefundVo refund : refundList) {
            // 退款订单清算
            if (refund.getDocumentType() == 0) {
                InternalReturnObject simpleOrderVoInternalRetObj = orderService.getOrderById(Long.parseLong(refund.getDocumentId()));
                if (simpleOrderVoInternalRetObj.getErrno() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "订单退款时订单信息获取失败");
                }
                //订单信息
                SimpleOrderVo simpleOrderVo = JSON.parseObject(JacksonUtil.toJson(simpleOrderVoInternalRetObj.getData()), SimpleOrderVo.class);
                var putRObj = putLiquadation(liquidationMap, simpleOrderVo.getShopId(), adminId, adminName);
                if (!putRObj.getCode().equals(ReturnNo.OK)) {
                    return putRObj;
                }

                Long orderShopRevenue = 0L;
                Long orderShopPoints = 0L;
                Long orderShopExpressFee = 0L;
                Long orderShopCommission = 0L;
                RevenueItemPoExample revenueItemPoExample = new RevenueItemPoExample();
                RevenueItemPoExample.Criteria revenueCriteria = revenueItemPoExample.createCriteria();

                revenueCriteria.andOrderIdEqualTo(simpleOrderVo.getId());

                List<RevenueItemPo> revenueItemPoList = revenueDao.getRevenueListByExample(revenueItemPoExample).getData();
                System.out.println("revenueItemPoList++++++++++++++++" + revenueItemPoList);
                for (RevenueItemPo revenueItemPo : revenueItemPoList) {
                    ExpenditureItemPo expenditureItemPo = cloneVo(revenueItemPo, ExpenditureItemPo.class);
                    expenditureItemPo.setRefundId(refund.getId());
                    expenditureItemPo.setRevenueId(revenueItemPo.getId());
                    expenditureItemPo.setAmount(-revenueItemPo.getAmount());
                    expenditureItemPo.setCommission(-revenueItemPo.getCommission());
                    expenditureItemPo.setPoint(-revenueItemPo.getPoint());
                    expenditureItemPo.setQuantity(revenueItemPo.getQuantity());
                    expenditureItemPo.setExpressFee(-revenueItemPo.getExpressFee());
                    expenditureItemPo.setShopRevenue(-revenueItemPo.getShopRevenue());
                    System.out.println("insertExpenditureItemPo========================" + expenditureItemPo);
                    ReturnObject ret = expenditureDao.insertExpenditureItemPo(expenditureItemPo, adminId, adminName);
                    if (ret.getCode().getCode() != 0) {
                        return ret;
                    }
                    orderShopRevenue += expenditureItemPo.getShopRevenue();
                    orderShopExpressFee += expenditureItemPo.getExpressFee();
                    orderShopPoints += expenditureItemPo.getPoint();
                    orderShopCommission += expenditureItemPo.getCommission();
                }
                Liquidation liquidation = liquidationMap.get(simpleOrderVo.getShopId());
                liquidation.setExpressFee(liquidation.getExpressFee() + (-simpleOrderVo.getExpressFee()));
                liquidation.setCommission(liquidation.getCommission() + orderShopCommission);
                liquidation.setPoint(liquidation.getPoint() + orderShopPoints);
                liquidation.setShopRevenue(liquidation.getShopRevenue() + orderShopRevenue);
                liquidationMap.put(simpleOrderVo.getShopId(), liquidation);

                platformCommission += orderShopCommission;
                platformExpressFee += (-simpleOrderVo.getExpressFee());
                refundExpFee += simpleOrderVo.getExpressFee();

            }
            System.out.println("LiquidationMap 3----------------------");
            System.out.println(liquidationMap);

            // 售后退款清算
            if (refund.getDocumentType() == 2L) {
                InternalReturnObject simpleAfterSaleVoInternalRetObj = afterSaleService.getAfterSalesById(Long.parseLong(refund.getDocumentId()));
                if (simpleAfterSaleVoInternalRetObj.getErrno() != 0) {
                    return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR, "售后退款清算时售后信息获取失败");
                }
                AftersalesVo simpleAfterSaleVo = JSON.parseObject(JacksonUtil.toJson(simpleAfterSaleVoInternalRetObj.getData()), AftersalesVo.class);
                var putRObj = putLiquadation(liquidationMap, simpleAfterSaleVo.getShopId(), adminId, adminName);
                if (!putRObj.getCode().equals(ReturnNo.OK)) {
                    return putRObj;
                }
                RevenueItemPoExample revenueItemPoExample = new RevenueItemPoExample();
                RevenueItemPoExample.Criteria revenueCriteria = revenueItemPoExample.createCriteria();

                revenueCriteria.andOrderitemIdEqualTo(simpleAfterSaleVo.getOrderItemId());
                List<RevenueItemPo> revenueItemPoList = null;
                try {
                    revenueItemPoList = revenueDao.getRevenueListByExample(revenueItemPoExample).getData();
                    if (revenueItemPoList.size() != 1) {
                        System.out.println("refundList Size: " + revenueItemPoList.size());
                        return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "入账单逻辑出错：orderItemId非唯一");
                    }
                } catch (Exception e) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, "入账单获取失败");
                }
                RevenueItemPo revenueItemPo = revenueItemPoList.get(0);
                Double ratio = (-simpleAfterSaleVo.getQuantity() / (double) revenueItemPo.getQuantity());
                System.out.println("ratio-------------" + ratio);
                ExpenditureItemPo expenditureItemPo = cloneVo(revenueItemPo, ExpenditureItemPo.class);
                expenditureItemPo.setRefundId(refund.getId());
                expenditureItemPo.setRevenueId(revenueItemPo.getId());
                expenditureItemPo.setQuantity(Math.toIntExact(simpleAfterSaleVo.getQuantity()));
                expenditureItemPo.setPoint((long) (revenueItemPo.getPoint() * ratio));
                expenditureItemPo.setCommission((long) (revenueItemPo.getCommission() * ratio));
                expenditureItemPo.setExpressFee(0L);
                expenditureItemPo.setAmount((long) (revenueItemPo.getAmount() * ratio));
                expenditureItemPo.setShopRevenue((long) (revenueItemPo.getShopRevenue() * ratio));
                System.out.println("revenueItemPo.getAmount()---------------" + revenueItemPo.getAmount());
                System.out.println("insertExpenditureItemPo========================" + expenditureItemPo.getShopRevenue() + " " + expenditureItemPo.getAmount());
                ReturnObject ret = expenditureDao.insertExpenditureItemPo(expenditureItemPo, adminId, adminName);
                if (ret.getCode().getCode() != 0) {
                    return ret;
                }

                Liquidation liquidation = liquidationMap.get(simpleAfterSaleVo.getShopId());
                liquidation.setShopRevenue(liquidation.getShopRevenue() + expenditureItemPo.getShopRevenue());
                liquidation.setPoint(liquidation.getPoint() + expenditureItemPo.getPoint());
                liquidation.setCommission(liquidation.getCommission() + expenditureItemPo.getCommission());
                liquidationMap.put(simpleAfterSaleVo.getShopId(), liquidation);

                platformCommission += expenditureItemPo.getCommission();
            }
            System.out.println("LiquidationMap 4----------------------");
            System.out.println(liquidationMap);
        }
        Liquidation liquidation = liquidationMap.get(0L);
        liquidation.setCommission(platformCommission);
        liquidation.setExpressFee(platformExpressFee);
        liquidationMap.put(0L, liquidation);
        ExpenditureItemPo expFeeExpenditureItemPo = new ExpenditureItemPo();
        expFeeExpenditureItemPo.setLiquidId(liquidationMap.get(0L).getId());
        expFeeExpenditureItemPo.setShopId(0L);
        expFeeExpenditureItemPo.setOrderId(0L);
        expFeeExpenditureItemPo.setOrderitemId(0L);
        expFeeExpenditureItemPo.setAmount(-refundExpFee);
        expFeeExpenditureItemPo.setExpressFee(-refundExpFee);
        ReturnObject expFeeExpenditureReturnObject = expenditureDao.insertExpenditureItemPo(expFeeExpenditureItemPo, adminId, adminName);
        if (expFeeExpenditureReturnObject.getCode().getCode() != 0) {
            return expFeeExpenditureReturnObject;
        }
        for (var temp : liquidationMap.entrySet()) {
            LiquidationPo liquidationPo = cloneVo(temp.getValue(), LiquidationPo.class);
            ReturnObject ret = liquidationDao.updateLiquidationPo(liquidationPo);
            if (ret.getCode().getCode() != 0) {
                return ret;
            }
        }

        System.out.println("清算结果如下：---------------------------------------------");
        System.out.println(liquidationMap);
        return new ReturnObject<>(ReturnNo.OK);
    }

    private ReturnObject putLiquadation(Map<Long, Liquidation> liquidationMap, Long shopId, Long adminId, String adminName) {
        if (!liquidationMap.containsKey(shopId)) {
            LiquidationPo tempLiquidationPo = new LiquidationPo();
            tempLiquidationPo.setShopId(shopId);
            ReturnObject ret = liquidationDao.insertLiquidationPo(tempLiquidationPo, adminId, adminName);
            if (ret.getCode().getCode() != 0) {
                return ret;
            }
            Liquidation tempLiquidationShop = cloneVo(ret.getData(), Liquidation.class);
            tempLiquidationShop.setCommission(0L);
            tempLiquidationShop.setShopId(shopId);
            tempLiquidationShop.setState((byte) 1);
            tempLiquidationShop.setLiquidDate(LocalDateTime.now());
            tempLiquidationShop.setShopRevenue(0L);
            tempLiquidationShop.setExpressFee(0L);
            tempLiquidationShop.setPoint(0L);
            liquidationMap.put(shopId, tempLiquidationShop);
        }
        return new ReturnObject();
    }
}
